----------------------------------------------------------------
-- Global Variables
----------------------------------------------------------------

ThreePartBar = {}

ThreePartBar.ProgressBarBG_BORDER           = {[0] = 0, [1] = 3};
ThreePartBar.VertProgressBarBG_BORDER       = {[0] = 4, [1] = 0};
ThreePartBar.ProgressFlag_VERTICAL_SPACE    = 7;

ThreePartBar.SIDE_LEFT                      = 1;
ThreePartBar.SIDE_RIGHT                     = 2;
ThreePartBar.SIDE_TOP                       = 3;
ThreePartBar.SIDE_BOTTOM                    = 4;

ThreePartBar.HORIZONTAL_BAR_HEIGHT = 28
ThreePartBar.VERTICAL_BAR_WIDTH = 28
ThreePartBar.HORIZONTAL_PIP_WIDTH = 18
ThreePartBar.HORIZONTAL_PIP_HEIGHT = 18
----------------------------------------------------------------
-- Local Variables
----------------------------------------------------------------

local ThreePartBarTracker = { }

-- This is the glue between the lua and xml data.
-- If the names of the progress bars change, then this
-- table must also change.
local ProgressBarData =
{
    [ThreePartBar.SIDE_LEFT]      = "Order",
    [ThreePartBar.SIDE_RIGHT]     = "Destruction",
    [ThreePartBar.SIDE_TOP]       = "Destruction",
    [ThreePartBar.SIDE_BOTTOM]    = "Order"
};

local OverrideTextureData =
{
    [ThreePartBar.SIDE_LEFT]    = { empty="Order-Limiter-horiz-empty" , full="Order-Limiter-horiz" },
    [ThreePartBar.SIDE_RIGHT]   = { empty="Dest-Limiter-horiz-empty", full="Dest-Limiter-horiz" },
    [ThreePartBar.SIDE_TOP]     = { empty="Dest-Limiter-vert-empty", full="Dest-Limiter-vert" },
    [ThreePartBar.SIDE_BOTTOM]  = { empty="Order-Limiter-vert-empty", full="Order-Limiter-vert" }
}
----------------------------------------------------------------
-- Local/Utility Functions
----------------------------------------------------------------

local function ReanchorPointBar (self)

    --DEBUG (L"ReanchorPointBar: ");
    --DEBUG (L"   bar:     "..StringToWString (self.barName));
    --DEBUG (L"   anchor:  "..StringToWString (self.parentName));
    
    local xBorder = ThreePartBar.ProgressBarBG_BORDER[0];
    local yBorder = ThreePartBar.ProgressBarBG_BORDER[1];
    
    -- Reanchor the bar main window
    -- This should update the initial anchors for all child windows:
    -- background, order, destruction
    WindowClearAnchors (self.barName);
    WindowAddAnchor (self.barName, "topleft", self.parentName, "topleft", 0, -yBorder);
    WindowAddAnchor (self.barName, "bottomright", self.parentName, "bottomright", 0, yBorder);    
    
    -- Set the correct width and height of the bar (at full size when anchored) so
    -- that we know the proper width to take a percentage of when reanchoring.
    self.barSize.width, self.barSize.height = WindowGetDimensions (self.barName);
    
    self.barSize.width  = self.barSize.width - xBorder;
    self.barSize.height = self.barSize.height - yBorder;
    
    -- Resize the direction indicators and the 65%/50% flags
    for side = ThreePartBar.SIDE_LEFT, ThreePartBar.SIDE_RIGHT do
        if (ProgressBarData[side] ~= nil and ProgressBarData[side] ~= "") then
        
            local directionIndicator = self.barName..ProgressBarData[side].."DirectionIndicator";
            local w, h = WindowGetDimensions (directionIndicator);
            
            local newWidth = (w * self.barSize.height) / h;
            
            -- Save this off to know when to hide the leading edge arrow in case 
            -- the bar value is too small.
            self.edgeWidth = newWidth;
            
            WindowSetDimensions (directionIndicator, newWidth, self.barSize.height); 
            
            -- The progress flags simply need to be reanchored, not resized...
            local progressFlag  = self.barName..ProgressBarData[side].."Flag";
            local flagPoint
            local connectorOffset = 0
            --DEBUG(L"SelfName: "..self.parentName)
            connectorOffset = self.barSize.width - self.barSize.width * 0.63            
            local vertOffset    = ThreePartBar.ProgressFlag_VERTICAL_SPACE;
            local anchorPt
            local connectorAnchorPt
            if (side == ThreePartBar.SIDE_LEFT) then
                flagPoint = "top"
                vertOffset = -vertOffset;
                anchorPt      = "topleft"
                connectorAnchorPt = "topright"
                connectorOffset = -connectorOffset
            else
                flagPoint = "bottom"
                anchorPt = "bottomright"
                connectorAnchorPt = "bottomleft"
                vertOffset = vertOffset + 2.5
            end
            

            
            local connectorName = self.barName..ProgressBarData[side].."Connector";  
            
            WindowClearAnchors (connectorName);
            WindowAddAnchor (connectorName, anchorPt, self.barName, anchorPt, 0, vertOffset);
            WindowAddAnchor (connectorName, connectorAnchorPt, self.barName, connectorAnchorPt, connectorOffset, vertOffset);
            
            WindowClearAnchors (progressFlag);
            WindowAddAnchor (progressFlag, connectorAnchorPt, connectorName, flagPoint, 0, 0);
        end
    end
end

local function ReanchorVerticalPointBar (self)
    local xBorder = ThreePartBar.VertProgressBarBG_BORDER[0];
    local yBorder = ThreePartBar.VertProgressBarBG_BORDER[1];
    
    -- Reanchor the bar main window
    -- This should update the initial anchors for all child windows:
    -- background, order, destruction
    WindowClearAnchors (self.barName);
    WindowAddAnchor (self.barName, "topleft", self.parentName, "topleft", 0, 0);
    WindowAddAnchor (self.barName, "bottomright", self.parentName, "bottomright", 0, 0);    
    
    -- Set the correct width and height of the bar (at full size when anchored) so
    -- that we know the proper width to take a percentage of when reanchoring.
    self.barSize.width, self.barSize.height = WindowGetDimensions (self.barName);
    
    self.barSize.width  = self.barSize.width - xBorder;
    self.barSize.height = self.barSize.height - yBorder;
    
    -- Reanchor the 65% flags
    for side = ThreePartBar.SIDE_TOP, ThreePartBar.SIDE_BOTTOM do
        if (ProgressBarData[side] ~= nil and ProgressBarData[side] ~= "") then
            -- The progress flags simply need to be reanchored
            local progressFlag  = self.barName..ProgressBarData[side].."Flag";
            local flagPoint
            local connectorOffset = self.barSize.height - self.barSize.height * 0.65
            local anchorPt
            local connectorAnchorPt
            local horizOffset = ThreePartBar.ProgressFlag_VERTICAL_SPACE
            if (side == ThreePartBar.SIDE_TOP) then
                flagPoint = "right"
                anchorPt      = "topright"
                connectorAnchorPt = "bottomright"
                connectorOffset = -connectorOffset
            else
                flagPoint = "left"
                anchorPt = "bottomleft"
                connectorAnchorPt = "topleft"
                horizOffset = -horizOffset
            end

            local connectorName = self.barName..ProgressBarData[side].."Connector";  
            
            WindowClearAnchors (connectorName);
            WindowAddAnchor (connectorName, anchorPt, self.barName, anchorPt, horizOffset, 0);
            WindowAddAnchor (connectorName, connectorAnchorPt, self.barName, connectorAnchorPt, horizOffset, connectorOffset);
            
            WindowClearAnchors (progressFlag);
            WindowAddAnchor (progressFlag, connectorAnchorPt, connectorName, flagPoint, 0, 0);
        end
    end
end

local function UpdateDirectionArrows (self, side, curVictoryPoints, pairingTotalPoints)

    local offset                = (curVictoryPoints / self.sumValue) * self.barSize.width;
    local directionIndicator    = self.barName..ProgressBarData[side].."DirectionIndicator";
    
    --DEBUG (L"UpdateDirectionArrow: ");
    --DEBUG (L"   Arrow:     "..StringToWString (directionIndicator));
    --DEBUG (L"   My PoolID: "..self.poolID);
    --DEBUG (L"   CurPoints: "..curVictoryPoints);
    --DEBUG (L"   Offset:    "..offset);       
 
    -- Check to make sure that the total uncontested points do not sum to 
    -- ThreePartBar.PointMax minus (some arbitrary epsilon value.)
    -- If they do, then hide the direction arrows.
    
    if (offset > self.edgeWidth and (pairingTotalPoints < (self.sumValue - 2))) then
        local point     = "left";   -- Point on the bar to anchor to
        local relative  = "right";  -- Point on the indicator that gets anchored.
        
        offset = offset + self.edgeShift;
        
        -- Harcoded wizardry.... :-/
        if (side == ThreePartBar.SIDE_RIGHT) then
            offset = -offset;
            point, relative  = relative, point;
        end
        
        if (WindowGetShowing (directionIndicator) == false) then
            WindowSetShowing (directionIndicator, true);
        end
        
        WindowClearAnchors (directionIndicator);
        WindowAddAnchor (directionIndicator, point, self.barName, relative, offset, 0);
    else
        WindowSetShowing (directionIndicator, false);
    end
end

local function UpdateVerticalDirectionArrows (self, side, curVictoryPoints, pairingTotalPoints)
end

local function UpdateProgressMeter (self, side, curVictoryPoints, curGhostPoints)
    local width  = ((curVictoryPoints / self.sumValue) * self.barSize.width);
    local height = ThreePartBar.HORIZONTAL_BAR_HEIGHT 
    local barName  = self.barName..ProgressBarData[side];
    local ghostBarName = self.barName..ProgressBarData[side].."Override"
    local ghostWidth = ((curGhostPoints / self.sumGhostValue) * (self.barSize.width*0.65));
    --[[DEBUG (L"UpdateProgressMeter: ")
    DEBUG (L"   Bar:       "..StringToWString (barName));
    DEBUG (L"   BarSize:   ("..self.barSize.width..L", "..self.barSize.height..L")")
    DEBUG (L"   CurPoints: "..curVictoryPoints)
    DEBUG (L"   Width:    "..width) 
    DEBUG (L"   OvrPoints: "..curGhostPoints)--]]
    if (width > 0) then
        local xBorder        = ThreePartBar.ProgressBarBG_BORDER[0];
        local yBorder        = ThreePartBar.ProgressBarBG_BORDER[1];       
        
        --width = width + 2*xBorder
        --height = height + 2*yBorder
        
        WindowSetDimensions( barName, width, height )            
        
        if (WindowGetShowing (barName) == false) then
            WindowSetShowing (barName, true);
        end
    else
        WindowSetShowing (barName, false);
    end  
    
    local ghostWidthOverride = 0
    ghostWidth = ghostWidthOverride
    
    if(ghostWidth > 0)
    then
        WindowSetDimensions( ghostBarName, ghostWidth, height )
        WindowSetAlpha( ghostBarName, 0.45 )
        if(WindowGetShowing( ghostBarName ) == false) 
        then
            WindowSetShowing( ghostBarName, true )
        end
    else
        WindowSetShowing( ghostBarName, false )
    end
    
    -- Update the Pips
    local overrideConnectorName = self.barName..ProgressBarData[side].."ConnectorLit"
    local progressFlag  = self.barName..ProgressBarData[side].."Flag";
    local ghostPoints = curGhostPoints
    local _, height = WindowGetDimensions (overrideConnectorName)  
    
    -- DEBUG(L"Ghost Points "..ghostPoints)    
    -- Set the "Lit" limiter when the override points = 6
    local newTexture = ""
    local pipMultiplier = 0
    if( ghostPoints >= 5 )
    then
        pipMultiplier = 5
        if( ghostPoints > 5 )
        then
            newTexture = OverrideTextureData[side].full
        else
            newTexture = OverrideTextureData[side].empty
        end                    
    else
        newTexture = OverrideTextureData[side].empty
        pipMultiplier = ghostPoints        
    end
    local newWidth = ThreePartBar.HORIZONTAL_PIP_WIDTH * pipMultiplier
    WindowSetDimensions( overrideConnectorName, newWidth, height )  
    DynamicImageSetTextureSlice( progressFlag, newTexture )
    

end

local function UpdateVerticalProgressMeter (self, side, curVictoryPoints, curGhostPoints)
    local width     = ThreePartBar.VERTICAL_BAR_WIDTH 
    local height    = ((curVictoryPoints / self.sumValue) * self.barSize.height);
    local barName   = self.barName..ProgressBarData[side];
    local ghostBarName = self.barName..ProgressBarData[side].."Override"
    local ghostHeight = ((curGhostPoints / self.sumGhostValue) * (self.barSize.height*0.65));
        
    if (height > 0) then
    
        local xBorder        = ThreePartBar.VertProgressBarBG_BORDER[0];
        local yBorder        = ThreePartBar.VertProgressBarBG_BORDER[1];    
        
        --width = width + 2*xBorder
        --height = height + 2*yBorder
        
        WindowSetDimensions( barName, width, height )            
        
        if (WindowGetShowing (barName) == false) then
            WindowSetShowing (barName, true);
        end      
    else
        WindowSetShowing (barName, false);
    end
    
    local ghostHeightOverride = 0
    ghostHeight = ghostHeightOverride
    
    if(ghostHeight > 0)
    then
        WindowSetDimensions( ghostBarName, width, ghostHeight )
        WindowSetAlpha( ghostBarName, 0.45 )
        if(WindowGetShowing( ghostBarName ) == false) 
        then
            WindowSetShowing( ghostBarName, true )
        end
    else
        WindowSetShowing( ghostBarName, false )
    end
    
    -- Update the Pips
    local overrideConnectorName = self.barName..ProgressBarData[side].."ConnectorLit"
    local progressFlag  = self.barName..ProgressBarData[side].."Flag";
    local ghostPoints = curGhostPoints
    local width, _ = WindowGetDimensions (overrideConnectorName)  
    
    --DEBUG(L"Ghost Points "..ghostPoints)    
    -- Set the "Lit" limiter when the override points = 6
    local newTexture = ""
    local pipMultiplier = 0
    if( ghostPoints >= 5 )
    then
        pipMultiplier = 5
        if( ghostPoints > 5 )
        then
            newTexture = OverrideTextureData[side].full
        else
            newTexture = OverrideTextureData[side].empty
        end                 
    else
        newTexture = OverrideTextureData[side].empty
        pipMultiplier = ghostPoints        
    end
    local newHeight = ThreePartBar.HORIZONTAL_PIP_HEIGHT * pipMultiplier
    WindowSetDimensions( overrideConnectorName, width, newHeight )  
    DynamicImageSetTextureSlice( progressFlag, newTexture )
end

-- If the slice names for the EA_VictoryPoints01_32b texture change than this has to change as well
local function UpdateVictoryStatus( self, directionName )
    if( self ~= nil and directionName ~= nil and directionName ~= "" ) then
        local leftTexSlice = "Order-Symbol-"..directionName
        local rightTexSlice = "Dest-Symbol-"..directionName
        local bRightWon = false
        local bLeftWon  = false
        local winLimit = 0.65
        local ghostWinLimit = 6


        -- Display the appropriate endcaps
        if( (self.leftValue / self.sumValue >= winLimit) or (self.leftGhostValue >= ghostWinLimit) ) then
            leftTexSlice = leftTexSlice.."-WIN"
            rightTexSlice = rightTexSlice.."-LOSE"
            bLeftWon = true
        elseif( self.rightValue / self.sumValue >= winLimit or (self.rightGhostValue >= ghostWinLimit) ) then
            rightTexSlice = rightTexSlice.."-WIN"
            leftTexSlice = leftTexSlice.."-LOSE"
            bRightWon = true
        end
        
        local leftEndCap  = self.barName..ProgressBarData[ThreePartBar.SIDE_LEFT].."EndCap"
        local rightEndCap = self.barName..ProgressBarData[ThreePartBar.SIDE_RIGHT].."EndCap"
        
        DynamicImageSetTextureSlice( leftEndCap, leftTexSlice )
        DynamicImageSetTextureSlice( rightEndCap, rightTexSlice )

        local leftConnector = self.barName..ProgressBarData[ThreePartBar.SIDE_LEFT].."Connector"
        local rightConnector = self.barName..ProgressBarData[ThreePartBar.SIDE_RIGHT].."Connector"
       --[[
        WindowSetShowing( rightConnector, not bRightWon )
        WindowSetShowing( rightConnector.."Win", bRightWon )
        WindowSetShowing( leftConnector, not bLeftWon )
        WindowSetShowing( leftConnector.."Win", bLeftWon )--]]
        WindowSetShowing( rightConnector.."Win", false )
        WindowSetShowing( leftConnector.."Win", false )
    end
end

local function UpdatePointBar (self)

    ----[[
    --DEBUG (L"Left: "..self.leftValue);
    --DEBUG (L"Right: "..self.rightValue);
    --]]
        
    UpdateProgressMeter(self,   ThreePartBar.SIDE_LEFT, self.leftValue, self.leftGhostValue);
    UpdateDirectionArrows(self, ThreePartBar.SIDE_LEFT, self.leftValue, self.sumValue);
    
    UpdateProgressMeter(self,   ThreePartBar.SIDE_RIGHT, self.rightValue, self.rightGhostValue);
    UpdateDirectionArrows(self, ThreePartBar.SIDE_RIGHT, self.rightValue, self.sumValue);

    UpdateVictoryStatus( self, "horiz" )
end

local function UpdateVerticalPointBar (self)
    --[[
    if (self.poolID == GameData.VictoryPoints.POOL_OVERALL) then
        DEBUG (L"Left: "..currentPool[1]);
        DEBUG (L"Right: "..currentPool[2]);
    end
    --]]
        
    UpdateVerticalProgressMeter(self,   ThreePartBar.SIDE_BOTTOM, self.leftValue, self.leftGhostValue);
    UpdateVerticalDirectionArrows(self, ThreePartBar.SIDE_BOTTOM, self.leftValue, self.sumValue);
    
    UpdateVerticalProgressMeter(self,   ThreePartBar.SIDE_TOP, self.rightValue, self.rightGhostValue);
    UpdateVerticalDirectionArrows(self, ThreePartBar.SIDE_TOP, self.rightValue, self.sumValue);
    
    UpdateVictoryStatus( self, "vert" )
end

----------------------------------------------------------------
-- ThreePartBar Functions
----------------------------------------------------------------

function ThreePartBar.Initialize()

   RegisterEventHandler( SystemData.Events.CAMPAIGN_ZONE_UPDATED,  "ThreePartBar.OnZoneUpdated")  
   
end

function ThreePartBar.Shutdown()

   UnregisterEventHandler( SystemData.Events.CAMPAIGN_ZONE_UPDATED,  "ThreePartBar.OnZoneUpdated")  

    -- The anchor points for the progress bars should destroy their children
    -- when they get destroyed, but just in case, I'll destroy the windows here.
    
    for k, v in pairs (ThreePartBarTracker) do
        if (nil ~= v.pointBarName) then
            DestroyWindow (v.pointBarName);
        end
    end
    
    ThreePartBarTracker = {};

end


function ThreePartBar.Create( pointBarName, parentName, vertical, scale )

    --DEBUG (L"CreatePointBar: ");
    --DEBUG (L"   id:      "..pointPoolID);
    --DEBUG (L"   name:    "..StringToWString (pointBarName));
    --DEBUG (L"   parent:  "..StringToWString (parentName));
    local windowTemplateName = "ThreePartProgressBar"
    if( vertical ) then
        windowTemplateName = "VerticalThreePartProgressBar"
    end
    
    CreateWindowFromTemplate(pointBarName, windowTemplateName, parentName);
    if( scale )
    then
        WindowSetScale( pointBarName, scale )
    end
        
    -- Map this bar's point pool id to a name so that there's an easy way to perform the updates.
    --   need to generate a unique ID

    -- Linear search - fast enough since this function isn't called often.
    --   Used since there's no generic ID generator in Lua
    local barId = 0
    while (ThreePartBarTracker[barId] ~= nil) do
        barId = barId + 1
    end
    
    -- record the ID so we can trigger callbacks
    WindowSetId(pointBarName, barId)

    ThreePartBarTracker[barId] = 
    { 
        poolID      = barId, 
        barName     = pointBarName,
        parentName  = parentName,
        edgeShift   = 1,
        edgeWidth   = 0,
        barSize     = 
        { 
            width   = 0, 
            height  = 0,
        },
        leftValue   = 0, -- This is the bottom value for the vertical bars
        rightValue  = 0, -- This is the top value for the vertical bars
        leftGhostValue = 0, -- Ghost values are used for zone override
        rightGhostValue = 0, -- Ghost values are used for zone override
        sumValue    = 100,
        sumGhostValue = 6,
        
        Initialize  = ReanchorPointBar,
        Update      = UpdatePointBar,        
        
        zoneId      = 0, -- Zone that is curently displayed on this bar.
    }
    
    if( vertical ) 
    then
        ThreePartBarTracker[barId].Update = UpdateVerticalPointBar
        ThreePartBarTracker[barId].Initialize = ReanchorVerticalPointBar
    end
    
    ThreePartBarTracker[barId]:Initialize()
    ThreePartBarTracker[barId]:Update()
    
    return barId;
end

function ThreePartBar.Destroy(barId)
    if (ThreePartBarTracker[barId] == nil) or (ThreePartBarTracker[barId].barName == nil) then
        return
    end

    DestroyWindow(ThreePartBarTracker[barId].barName)
end

function ThreePartBar.Hide(barId)
    if (ThreePartBarTracker[barId] == nil) or (ThreePartBarTracker[barId].barName == nil) then
        return
    end
    
    WindowSetShowing(ThreePartBarTracker[barId].barName, false)
end

function ThreePartBar.Show(barId)
    if (ThreePartBarTracker[barId] == nil) or (ThreePartBarTracker[barId].barName == nil) then
        return
    end

    WindowSetShowing(ThreePartBarTracker[barId].barName, true)
end

-- For VerticalThreePartBars this is basically SetBottom, this might be moved to its own function
function ThreePartBar.SetLeft(barId, value)

    -- DEBUG(L"ThreePartBar.SetLeft("..barId..L", "..value..L")")
    -- DUMP_TABLE(ThreePartBarTracker[barId])

    if ( (ThreePartBarTracker[barId].rightValue + value) <= ThreePartBarTracker[barId].sumValue ) then
        ThreePartBarTracker[barId].leftValue = value;
        ThreePartBarTracker[barId]:Update();
    end

end

-- For VerticalThreePartBars this is basically SetTop, this might be moved to its own function
function ThreePartBar.SetRight(barId, value)
    -- DUMP_TABLE(ThreePartBarTracker[barId])
    if ( (ThreePartBarTracker[barId].leftValue + value) <= ThreePartBarTracker[barId].sumValue ) then

        ThreePartBarTracker[barId].rightValue = value;
        ThreePartBarTracker[barId]:Update();
    end

end

function ThreePartBar.GetRightSidePercent( barId )
    if( barId ~= nil and ThreePartBarTracker[barId] ~= nil ) then 
        return  ThreePartBarTracker[barId].rightValue / ThreePartBarTracker[barId].sumValue
    end
    
    return 0
end

function ThreePartBar.GetLeftSidePercent( barId )
    if( barId ~= nil and ThreePartBarTracker[barId] ~= nil ) then
        return  ThreePartBarTracker[barId].leftValue / ThreePartBarTracker[barId].sumValue
    end
    
    return 0
end

function ThreePartBar.Reanchor( barId )
    ThreePartBarTracker[barId]:Initialize()
end


function ThreePartBar.GetBarIdFromParent( parentName )
    
    for barId, barData in pairs( ThreePartBarTracker )
    do
        if( barData.parentName == parentName)
        then
            return barId
        end
    end

end

function ThreePartBar.SetZone( barId, zone )
    
    if( ThreePartBarTracker[barId] == nil )
    then
        ERROR( L"ThreePartBar.SetZone( barId, zone): barId is nil" )
        return
    end

    ThreePartBarTracker[barId].zoneId = zone
    ThreePartBar.UpdateBar( barId )
end

function ThreePartBar.GetZone( barId )
    
    if( ThreePartBarTracker[barId] == nil )
    then
        ERROR( L"ThreePartBar.GetZone( barId, zone): barId is nil" )
        return
    end
    
    return ThreePartBarTracker[barId].zoneId
end


function ThreePartBar.OnZoneUpdated( zoneId )
    --DEBUG(L"ThreePartBar.OnZoneUpdated(): zoneId = "..zoneId )
    
    for barId, barData in pairs( ThreePartBarTracker )
    do
        if( barData.zoneId == zoneId)
        then
            ThreePartBar.UpdateBar( barId )
        end
    end

end

function ThreePartBar.UpdateBar( barId )

    -- Access the control data
    local zoneData = GetCampaignZoneData( ThreePartBarTracker[barId].zoneId )
    if( zoneData == nil ) 
    then
        ERROR( L" Zone Data nil " )
        return 
    end    
                                                                          
    --DEBUG(L"ThreePartBar.UpdateBar(): BarId="..barId..L" ZoneId="..zoneData.zoneId..L" Order="..zoneData.controlPoints[ GameData.Realm.ORDER ]..L" Destruction="..zoneData.controlPoints[ GameData.Realm.DESTRUCTION ] )
    
    -- Update all of the values
    ThreePartBarTracker[barId].leftValue = zoneData.controlPoints[ GameData.Realm.ORDER ]            
    ThreePartBarTracker[barId].rightValue = zoneData.controlPoints[ GameData.Realm.DESTRUCTION ]     
    ThreePartBarTracker[barId].leftGhostValue = zoneData.overridePoints[ GameData.Realm.ORDER ]
    ThreePartBarTracker[barId].rightGhostValue = zoneData.overridePoints[ GameData.Realm.DESTRUCTION ]
    
    -- Update the Display
    ThreePartBarTracker[barId]:Update()
    
    local barName = ThreePartBarTracker[barId].barName    
    local orderOverride = zoneData.overridePoints[ GameData.Realm.ORDER ] 
    local destructionOverride = zoneData.overridePoints[ GameData.Realm.DESTRUCTION ]
    -- Update the Lock
    WindowSetShowing( barName.."Lock", ( (zoneData.isLocked) or (orderOverride==6) or (destructionOverride==6) )   )
    
    -- Hide the connection flags when locked
    WindowSetShowing( barName.."OrderConnector", not zoneData.isLocked )
    WindowSetShowing( barName.."DestructionConnector", not zoneData.isLocked  )    
    WindowSetShowing( barName.."OrderFlag", not zoneData.isLocked  )
    WindowSetShowing( barName.."DestructionFlag", not zoneData.isLocked  )
    --DUMP_TABLE(zoneData)
  
end


function ThreePartBar.DefaultOnMouseoverCallback()

    local barId = ThreePartBar.GetBarIdFromParent( SystemData.ActiveWindow.name )

    ThreePartBar.CreateDefaultZoneControlTooltip(  ThreePartBar.GetZone( barId ) , SystemData.ActiveWindow.name )
    Tooltips.AnchorTooltip( Tooltips.ANCHOR_WINDOW_LEFT )

end

function ThreePartBar.CreateDefaultZoneControlTooltip( zoneId, windowName )

    local zoneData  = GetCampaignZoneData( zoneId )    
    if (zoneData == nil) 
    then
        ERROR( L" Zone Data nil " )
        return
    end

    -- First line: <realm> controls <zone>

    local realmName = GetRealmName( zoneData.controllingRealm )    
    local zoneName  = GetZoneName(zoneData.zoneId )

    -- (1) Control Info
    local controlString = GetStringFormatFromTable( "WorldControl", StringTables.WorldControl.LABEL_CONTROL, { realmName, zoneName } )
    
    Tooltips.CreateTextOnlyTooltip( SystemData.ActiveWindow.name )
    Tooltips.SetTooltipText( 1, 1, controlString )
    Tooltips.SetTooltipColorDef( 1, 1, Tooltips.COLOR_HEADING )
    
    -- (2) Control Description
    Tooltips.SetTooltipText( 2, 1, GetStringFromTable("WorldControl", StringTables.WorldControl.TEXT_CONTROLBAR_POINTS_DESCRIPTION) )        
        
    ThreePartBar.AddToolTipBonusSection( zoneData, 3 )  
    Tooltips.Finalize()

end

function ThreePartBar.AddToolTipBonusSection( zoneData, startIndex )

    local index = startIndex       

    -- Bonus Title
    Tooltips.SetTooltipText( index, 1, GetStringFromTable("WorldControl", StringTables.WorldControl.TEXT_CONTROL_BONUS_TITLE) )
    Tooltips.SetTooltipColorDef( index, 1, Tooltips.COLOR_HEADING )
    index = index + 1
    
    -- Bonus Description
    Tooltips.SetTooltipText( index, 1, GetStringFromTable("WorldControl", StringTables.WorldControl.TEXT_CONTROL_BONUS_DESCRIPTION) )
    index = index + 1
          
    -- Renown - Not avail when the player is outside the region, will be nil
    if( zoneData.bonuses.renownGain )
    then
        ThreePartBar.SetToolTipBonusValue( index, zoneData.bonuses.renownGain, StringTables.WorldControl.TEXT_CONTROL_BONUS_RENOWN_GAIN )
        index = index + 1
    end
    
    -- Influence
    ThreePartBar.SetToolTipBonusValue( index, zoneData.bonuses.influenceGain, StringTables.WorldControl.TEXT_CONTROL_BONUS_INFLUENCE_GAIN )
    index = index + 1
    
    -- Merchant Buy From
    ThreePartBar.SetToolTipBonusValue( index, zoneData.bonuses.merchantBuyFrom, StringTables.WorldControl.TEXT_CONTROL_BONUS_MERCHANT_BUY_FROM )
    index = index + 1
    
    -- Merchant Sell To
    ThreePartBar.SetToolTipBonusValue( index, zoneData.bonuses.merchantSellTo, StringTables.WorldControl.TEXT_CONTROL_BONUS_MERCHANT_SELL_TO )
    index = index + 1    

end

function ThreePartBar.SetToolTipBonusValue( index, bounusValue, stringId )

    -- Show a + or - in the sign in the text
    local signValue = 1
    if( bounusValue < 0 )
    then
        signValue = 2
        bounusValue = -bounusValue
    end
        
    -- Color the Bonus Green when it has a value
    local color = DefaultColor.LIGHT_GRAY
    if( bounusValue > 0 )
    then 
        color = DefaultColor.GREEN
    end  

    local text = GetStringFormatFromTable( "WorldControl", stringId, { L""..bounusValue, L""..signValue }  )
    Tooltips.SetTooltipText( index, 1, text )       
    Tooltips.SetTooltipColorDef( index, 1, color )
end
